package com.itheima.Timer;

import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class RoundDemo {
    //小轮槽数
    int size1=10;
    //大轮槽数
    int size2=5;
    //小轮，数组，每个元素是一个链表
    LinkedList<RoundTask>[] t1 = new LinkedList[size1];
    //大轮
    LinkedList<RoundTask>[] t2 = new LinkedList[size2];
    //小轮计数器，指针跳动的格数，每秒加1
    final AtomicInteger flag1=new AtomicInteger(0);
    //大轮计数器，指针跳动个格数，即每10s加1
    final AtomicInteger flag2=new AtomicInteger(0);

    //调度器，拖动指针跳动
    ScheduledExecutorService service = Executors.newScheduledThreadPool(2);

    public RoundDemo(){
        //初始化时间轮
        for (int i = 0; i < size1; i++) {
            t1[i]=new LinkedList<>();
        }
        for (int i = 0; i < size2; i++) {
            t2[i]=new LinkedList<>();
        }
    }

    //打印时间轮的结构，数组+链表
    void print(){
        System.out.println("t1:");
        for (int i = 0; i < t1.length; i++) {
            System.out.println(t1[i]);
        }
        System.out.println("t2:");
        for (int i = 0; i < t2.length; i++) {
            System.out.println(t2[i]);
        }
    }
    //添加任务到时间轮
    void add(RoundTask task){
        int delay = task.delay;
        if (delay < size1){
            //10以内的，在小轮，槽取余数
            t1[delay%size1].addLast(task);
        }else {
            //超过小轮的放入大轮，槽除以小轮的长度
            t2[delay/size1].addLast(task);
        }
    }

    void startT1(){
        //每秒执行一次，推动时间轮旋转，取到任务立马执行
        service.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                int point = flag1.getAndIncrement()%size1;
                System.out.println("t1 -----> slot "+point);
                LinkedList<RoundTask> list = t1[point];
                if (!list.isEmpty()){
                    //如果当前槽内有任务，取出来，依次执行，执行完移除
                    while (list.size() != 0){
                        list.getFirst().run();
                        list.removeFirst();
                    }
                }

            }
        },0,1, TimeUnit.SECONDS);
    }
    void startT2(){
        //每10秒执行一次，推动时间轮旋转，取到任务下方到t1
        service.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                int point = flag2.getAndIncrement()%size2;
                System.out.println("t2 =====> slot "+point);
                LinkedList<RoundTask> list = t2[point];
                if (!list.isEmpty()){
                    //如果当前槽内有任务，取出，放到定义的小轮
                    while (list.size() != 0){
                        RoundTask task = list.getFirst();
                        //放入小轮哪个槽呢？小轮的槽按10取余数
                        t1[task.delay % size1].addLast(task);
                        //从大轮中移除
                        list.removeFirst();
                    }
                }
            }
        },0,10, TimeUnit.SECONDS);
    }

    public static void main(String[] args) {
        RoundDemo roundDemo = new RoundDemo();
        //生成100个任务，每个任务的延迟时间随机
        for (int i = 0; i < 100; i++) {
            roundDemo.add(new RoundTask(i,new Random().nextInt(50)));
        }
        //打印，查看时间轮任务布局
        roundDemo.print();
        //启动大轮
        roundDemo.startT2();
        //小轮启动
        roundDemo.startT1();

    }



}
